package fi.bluepill.server.rest;

import fi.bluepill.server.model.RateableEntity;
import fi.bluepill.server.model.Rating;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import rip.core.Transactional;

import javax.persistence.Query;
import java.util.List;

public class RatingService extends BluepillService {
    @Transactional
    public void add() {
        assertAuthentication();

        RatingAddMessage input = read(RatingAddMessage.class);

        RateableEntity entity = jpaQuery(RateableEntity.class, "select re from RateableEntity re where re.uuid = :uuid", qp("uuid", input.getEntityId()));

        Rating rating = new Rating();
        rating.setMessage(input.getMessage());
        rating.setRating(input.getRating());
        rating.setUsername(user(userId()).getUsername());
        rating.setUserId(userId());
        rating.setEntityId(entity.getUuid());

        jpa().persist(rating);

        entity.addRating(rating);

        jpa().merge(entity);

        ObjectNode m = okMessage();
        m.put("uuid", rating.getUuid());

        write(m);
    }

    public void list() {
        Query q = jpa().createQuery("select r from Rating r where r.entityId = :entityId order by r.createdTime");
        q.setParameter("entityId", queryParameter("entityId"));

        if (!isEmpty(queryParameter("max_results")))
            q.setMaxResults(Integer.parseInt(queryParameter("max_results")));
        else
            q.setMaxResults(10);

        List<Rating> ratingList = q.getResultList();

        q = jpa().createQuery("select re from RateableEntity re where re.uuid = :uuid");
        q.setParameter("uuid", queryParameter("entityId"));

        RateableEntity entity = (RateableEntity)q.getSingleResult();

        ObjectNode m = okMessage();
        m.put("average", entity.getAverageRating());
        m.put("no_of_ratings", entity.getRatingsCount());

        ArrayNode ratings = m.putArray("ratings");

        for (Rating rating : ratingList) {
            ObjectNode ratingNode = json().createObjectNode();
            ratingNode.put("message", rating.getMessage());
            ratingNode.put("username", rating.getUsername());
            ratingNode.put("rating", rating.getRating());
            ratingNode.put("createdTime", rating.getCreatedTime());
            ratingNode.put("uuid", rating.getUuid());
            ratings.add(ratingNode);
        }

        write(m);
    }
}
